#include "cc1111rf.h"
#include "global.h"
#include "string.h"
#include <stdio.h>

#include "immefont.h"

#include "blackhat-game2.h"
#include "blackhat-game2-immeio.h"

/* Clear the transmit data struct */
void reset_trans_data(TransData *in_td){
#ifdef LARGE_GAME
    in_td->session = 0;
#endif
    in_td->plen = 0;
    in_td->type = 0;
    strcpy(in_td->bufdata, 0);
#ifdef LARGE_GAME
    in_td->crc  = 0;
#endif
}

/*
// FIXME: Remove, We don't need this anymore as sending TransData by itself is sufficiant
// rtn_data concantenates the TransData elements for sending via a packet 
void rtn_data(TransData in_td, u8 *tmpdata){

    u8* dummy_td = (u8*) in_td;
    //int stlen = sizeof(TransData);
    int stlen = in_td->plen + 1;

    for (;stlen>0;stlen--){
        *tmpdata++ = *dummy_td++;
    }

}
*/

/* pad data with string specified by PACKETPAD */
void pad_data(TransData *in_td){

    int cnt = 0;
    u8 *padding = (u8*) PACKETPAD;
    //u8 *tmp_str0 = in_td->bufdata;
    u8 *tmp_str0 = (u8*) in_td->bufdata;
    u8 tmp_str1[MESSMAX];
    u8 *tmp_str2 = (u8*) tmp_str1;
    u8 stlen = in_td->plen - 1;

    for(;cnt < MESSMAX;cnt++){
        // Copy our original string into the tmp buffer
        if (stlen > cnt){
            *tmp_str2++ = *tmp_str0++;
        }else{
            // When done fill with out padding
            *tmp_str2++ = *padding++;
        }
    }

    strcpy(in_td->bufdata,tmp_str1);
    //in_td->plen = strlen(in_td->bufdata) + 1;
    in_td->plen = MESSMAX;

}

/* build request message and return length */
void build_packet(TransData *in_td, int pbyte, u8 *sdata){

    reset_trans_data(in_td);

    // Nested IF method. This should work better than the switch statement, but it doesn't.
    // Same as switch
    if (pbyte == 0){
        // Ordered request logic as it happens in sequence
        in_td->plen = 1;
        in_td->type = (u8) INITBYTE;
        strcpy(in_td->bufdata,0);
    }else if (pbyte == 1) {
        //in_td->plen = 1 + strlen(sdata);         // FIXME: String length is blowing up here because sdata is not null terminated
        in_td->plen = 3;                           // FIXME: Hard coded size because I know it will be three bytes
        in_td->type = (u8) SECBYTE;
        strcpy(in_td->bufdata, sdata);
    }else if (pbyte == 2) {
        //in_td->plen = 1 + strlen(sdata);
        in_td->plen = 2;                           // FIXME: Hard coded size because I know it will be two bytes
        in_td->type = (u8) SENDBYTE;             // should be one byte which tells receive what to send back
        strcpy(in_td->bufdata, sdata);
    }else if (pbyte == 105) {
        in_td->plen = 1;
        in_td->type = (u8) OKBYTE;
        strcpy(in_td->bufdata,0);
    }else if (pbyte == 153) {
        in_td->plen = 1;
        in_td->type = (u8) NOKBYTE;
        strcpy(in_td->bufdata,0);
    }else if (pbyte == 255) {
        in_td->plen = 1;
        in_td->type = (u8) DONEBYTE;
        strcpy(in_td->bufdata,0);
    }else {
        in_td->plen = 1 + strlen("ERROR");
        in_td->type = (u8) NOKBYTE;
        strcpy(in_td->bufdata, "ERROR");
    }
}

/*************************************************************************************************
 *  here begins the initialization stuff... this shouldn't change much between firmwares or      *
 *  devices.                                                                                     *
 *************************************************************************************************/

static void appInitRf(void)
{
    IOCFG2      = 0x00;
    IOCFG1      = 0x00;
    IOCFG0      = 0x00;
    SYNC1       = SYNC_BYTE1; //0x0c;   // Used with MDMCFG2 set SYNC_ON
    SYNC0       = SYNC_BYTE0; //0x4e;
    PKTLEN      = 0xff;
    PKTCTRL1    = 0x20;//0x40; // PQT threshold  - was 0x00
#ifndef VAR_PACKET          // Used to set packet length and if we are using CRC
    #ifdef LARGE_GAME
        PKTCTRL0    = 0x04; // CRC:4 Fixed Len
    #else
        PKTCTRL0    = 0x00; // No CRC Fixed Len
    #endif
#else
    #ifdef LARGE_GAME
        PKTCTRL0    = 0x05;// Variable LEN:, CRC:4
    #else
        PKTCTRL0    = 0x01;// Variable LEN:, No CRC
    #endif
#endif
    ADDR        = 0x00;
    CHANNR      = 0x00;

    FSCTRL1     = 0x06;
    FSCTRL0     = 0x00;


    MDMCFG4     = 0xca;
    MDMCFG3     = 0x83;//0xa3;//0x83;
    //MDMCFG2     = 0x04;//0x03;//0x10;  // SYNC_MODE - 000-nopreamble/syncbits...111-30/32+carriersense
    MDMCFG2     = SYNC_ON; //4 is off, 3 is on
    //MDMCFG2     = 0x73; //MOD_GFSK with SYNC On 
    MDMCFG1     = 0x23;//0x22;
    MDMCFG0     = 0x11;//0xf8;
    DEVIATN     = 0x35;
    MCSM2       = 0x07;             // RX_TIMEOUT
    MCSM1       = 0x3f;//0x30;             // CCA_MODE RSSI below threshold unless currently recvg pkt - always end up in RX mode
    MCSM0       = 0x18;             // fsautosync when going from idle to rx/tx/fstxon
    FOCCFG      = 0x16;
    BSCFG       = 0x6c;
    //AGCCTRL2    = 0x43;           // Highest DVGA Gain cannot be used
    AGCCTRL2    = 0x03;
    AGCCTRL1    = 0x40;
    AGCCTRL0    = 0x91;
    FREND1      = 0x56;
    FREND0      = 0x10;
    FSCAL3      = 0xe9;
    FSCAL2      = 0x2a;
    FSCAL1      = 0x00;
    FSCAL0      = 0x1f;
    TEST2       = 0x81; // low data rates, increased sensitivity - was 0x88
    TEST1       = 0x35; // always 0x31 in tx-mode, for low data rates, increased sensitivity - was 0x31
    TEST0       = 0x09;
    PA_TABLE0   = 0x8e;

    //FREQ2       = 0x23; // 0x23313b == 914.999969
    //FREQ1       = 0x31;
    //FREQ0       = 0x3b;
    setRadioFrequency(START_FREQ);  //This should figure out the proper frequency and set values
    
}
